feat: use git remote URL for cross-machine project memory sync#43
feat: use git remote URL for cross-machine project memory sync#43jim80net wants to merge 4 commits intosupermemoryai:mainfrom
Conversation
Resolves supermemoryai#38 Problem: - Project memories use directory path hash as identifier - Different machines have different paths for the same project - Result: project memories don't sync across machines - Setting projectContainerTag affects ALL projects (memory pollution) Solution: - Use git remote origin URL as primary project identifier - Same git remote = same project tag across all machines - Fallback to directory hash if no git remote Benefits: - Transparent: works without user configuration - Automatic sync for same repository across machines - Automatic isolation for different repositories - Backward compatible: falls back to existing behavior
| const remoteUrl = getGitRemoteUrl(directory); | ||
| if (remoteUrl) { | ||
| return `${CONFIG.containerTagPrefix}_project_${sha256(remoteUrl)}`; | ||
| } |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Valid finding. Existing users have memories stored under sha256(directory). Switching to sha256(normalizeGitUrl(remoteUrl)) orphans those memories on upgrade — not just when adding a remote after creation.
Fixed in a88b0bd: all read operations (search, list, compaction context fetch) now query both the canonical remote-based tag and the legacy directory-based tag, deduplicating by memory ID. Writes go only to the new tag, so memories gradually migrate forward.
SSH and HTTPS URLs for the same repo (e.g. git@github.com:user/repo.git vs https://github.com/user/repo) produced different hashes, silently breaking cross-machine memory sync. Normalize URLs to a canonical form before hashing. Also restores trailing newline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| return url | ||
| .replace(/^[a-z+]+:\/\//, "") // strip protocol (https://, git://, ssh://) | ||
| .replace(/^[^@]+@/, "") // strip user@ prefix (git@, user@) | ||
| .replace(/:(\d+)\//, "/$1/") // preserve port numbers (e.g. :8080/) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Evaluated and this is not a real issue. The port number is part of the server identity — if a server runs on port 2222, all clones will include :2222 and they normalize consistently to gitlab.local/2222/user/repo.
The only failure case would be one machine using ssh://git@gitlab.local:22/user/repo.git (explicitly specifying the default port) while another uses ssh://git@gitlab.local/user/repo.git. This is vanishingly rare — no standard git tooling generates URLs with the default port.
Stripping port numbers would actually be worse: it would incorrectly unify repos from different servers on the same host but different ports (e.g., a staging and production GitLab on the same machine).
… upgrade Existing users have project memories stored under sha256(directory). After switching to sha256(normalizeGitUrl(remoteUrl)), those memories become silently inaccessible. Fix by querying both the new canonical tag and the legacy directory-based tag for all read operations (search, list, compaction context), deduplicating by memory ID. Writes go only to the new canonical tag so memories gradually migrate. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
src/index.ts
Outdated
| const currentMems = result.memories || []; | ||
| const legacyMems = legacyListResult.success ? (legacyListResult.memories || []) : []; | ||
| const listSeenIds = new Set(currentMems.map((m: any) => m.id)); | ||
| const memories = [...currentMems, ...legacyMems.filter((m: any) => !listSeenIds.has(m.id))]; |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Valid. All three merge sites now apply .slice(0, limit) after dedup. Fixed in ff06340.
Merging memories from both current and legacy tags could return up to double the configured limit. Apply slice after dedup in all three merge sites: initial context injection, list tool, and compaction fetch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Resolves #38
Uses git remote origin URL as the project identifier for memory container tags, enabling automatic cross-machine project memory synchronization.
Problem
Currently, project memories use
sha256(directory)as the identifier:projectContainerTagaffects ALL projects (memory pollution)Solution
Benefits
Test Plan
Example
Machines A and B now share project memories. Machine C has its own isolated memories.